from datetime import datetime
import hashlib
import pathlib
import os
from flask import Flask, render_template, request
from flask_sqlalchemy import SQLAlchemy
import sqlalchemy as sa

app = Flask(__name__)
# 配置 sqlite 数据库 默认生成在 项目目录下的 instance 中
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.db'
# 视频默认上传地址
app.config['UPLOAD_FOLDER'] = 'static/upload/video'

db = SQLAlchemy()
db.init_app(app)


class Movie(db.Model):
    __tablename__ = 'movie'
    id = sa.Column(sa.Integer, primary_key=True, autoincrement=True)
    name = sa.Column(sa.String(255), nullable=False)
    url = sa.Column(sa.String(255), nullable=False)
    m3u8_url = sa.Column(sa.String(255), nullable=False)
    create_at = sa.Column(sa.DateTime, default=datetime.now)


@app.cli.command()
def create():
    db.drop_all()
    db.create_all()


@app.route('/')
def index():
    q = db.select(Movie)
    movie_list = db.session.execute(q).scalars()
    return render_template('index.html', movie_list=movie_list)


@app.get('/video_view')
def video_view():
    vid = request.args.get('video_id')
    video = Movie.query.get(vid)
    url = video.m3u8_url
    url = url.replace('\\', '/')
    return render_template('video_view.html', url=url)


@app.get('/upload_movie')
def upload_movie():
    return render_template('video_upload.html')


@app.post('/upload_movie')
def upload():
    file = request.files['file']
    if file:
        filename = file.filename
        # 读取视频内容
        content = file.read()
        # 获取视频的md5值
        hex_name = hashlib.md5(content).hexdigest()
        # 获取文件后缀
        suffix = pathlib.Path(filename).suffix
        # 拼接新的名字md5+后缀名
        new_filename = hex_name + suffix
        upload_dir = pathlib.Path(app.config['UPLOAD_FOLDER'])
        # 获取写入地址
        new_path = upload_dir.joinpath(new_filename)
        # 写入文件
        open(new_path, 'wb').write(content)
        # 处理为 m3u8 格式
        m3u8_path = upload_dir.parent.joinpath('m3u8')
        if not m3u8_path.exists():
            m3u8_path.mkdir()
        current_dir = m3u8_path.joinpath(hex_name)
        if not current_dir.exists():
            current_dir.mkdir()
        # 先生成一整个ts文件
        cli1 = f'ffmpeg -y -i {new_path} -vcodec copy -acodec copy -bsf:v h264_mp4toannexb {str(current_dir)}/index.ts'
        os.system(cli1)
        cli2 = f'ffmpeg -i {str(current_dir)}/index.ts -c copy -map 0 -f segment -segment_list {str(current_dir)}/index.m3u8 -segment_time 10 "{str(current_dir)}/index-%04d.ts"'
        os.system(cli2)
        # 创建模型并保存到数据库
        mv = Movie()
        mv.url = '/' + str(new_path)
        mv.name = filename
        mv.m3u8_url = '/' + str(current_dir) + '/index.m3u8'
        db.session.add(mv)
        db.session.commit()
        return {'code': 200, 'msg': '上传文件成功'}
    return {'code': 500, 'msg': '上传文件失败'}


if __name__ == '__main__':
    app.run(debug=True)
